#ifndef _GAF_API_H
#define _GAF_API_H

#include <stdint.h>

#include "gap_api.h"

/// Length of Codec ID value
#define GAF_CODEC_ID_LEN                (5)

#define GAF_KEY_LEN                     (16)

/// Event ID for callback
enum gaf_cb_event_id
{
    GAF_BAP_CONFIGURED,
    GAF_BAP_BC_SRC_GROUP_ADDED,
    GAF_BAP_BC_SRC_GROUP_SET,
    GAF_BAP_BC_SRC_SUBGROUP_SET,
    GAF_BAP_BC_SRC_STREAM_SET,
    GAF_BAP_BC_SRC_PA_ENABLED,
    GAF_BAP_BC_SRC_ENABLED,
    GAF_BAP_BC_SRC_STREAM_STARTED,
    GAF_BAP_BC_SCAN_STARTED,
    GAF_BAP_BC_SCAN_STOPPED,
    GAF_BAP_BC_SCAN_PA_SYNC_STARTED,
    GAF_BAP_BC_SCAN_PARAM_SET,
    GAF_BAP_BC_SCAN_TIMEOUT,
    GAF_BAP_BC_SCAN_REPORT,
    GAF_BAP_BC_SCAN_PA_ESTABLISHED,
    GAF_BAP_BC_SCAN_PA_TERMINATED,
    GAF_BAP_BC_SCAN_PA_REPORT,
    GAF_BAP_BC_SCAN_BIG_INFO_REPORT,
    GAF_BAP_BC_SCAN_GROUP_REPORT,
    GAF_BAP_BC_SCAN_SUBGROUP_REPORT,
    GAF_BAP_BC_SCAN_STREAM_REPORT,
    GAF_BAP_BC_SINK_ENABLED,
    GAF_BAP_BC_SINK_STREAM_STARTED,
    GAF_BAP_BC_SINK_ISO_DATA,

    GAF_BAP_CAPA_CLI_BOND_DATA ,
    GAF_BAP_CAPA_CLI_RECORD,
    GAF_BAP_CAPA_CLI_LOCATION,
    GAF_BAP_CAPA_CLI_CONTEXT,
    GAF_BAP_CAPA_CLI_CFG,
    GAF_BAP_CAPA_CLI_SVC_CHANGED,
    GAF_BAP_CAPA_SRV_BOND_DATA,
    GAF_BAP_CAPA_SRV_LOCATION,

    GAF_BAP_UC_CLI_BOND_DATA,
    GAF_BAP_UC_CLI_CFG,
    GAF_BAP_UC_CLI_CIS_STATE,
    GAF_BAP_UC_CLI_STATE_EMPTY,
    GAF_BAP_UC_CLI_STATE_CODEC,
    GAF_BAP_UC_CLI_STATE_QOS,
    GAF_BAP_UC_CLI_STATE_METADATA,
    GAF_BAP_UC_CLI_ERROR,
    GAF_BAP_UC_CLI_SVC_CHANGED,
    GAF_BAP_UC_CLI_ISO_DATA,
    GAF_BAP_UC_SRV_BOND_DATA,
    GAF_BAP_UC_SRV_ASE_STATE,
    GAF_BAP_UC_SRV_CIS_STATE,
    GAF_BAP_UC_SRV_ISO_DATA,

    GAF_BAP_UC_SRV_CFG_CODEC_REQ,
    GAF_BAP_UC_SRV_ASE_ENABLE_REQ,
    GAF_BAP_UC_SRV_UPDATE_METADATA_REQ,
    GAF_BAP_UC_SRV_ASE_RELEASE_REQ,

    GAF_BAP_OP_CMP,

    GAF_UNHANDLED_MSG,
};

/** @defgroup GAF OPERARIONS COMPLETE DEFINES, used with GAF_BAP_OP_CMP
 * @{
 */
#define GAF_OP_BAP_CAPA_CLI_DISCOVER                0x01
#define GAF_OP_BAP_CAPA_CLI_GET                     0x02
#define GAF_OP_BAP_CAPA_CLI_SET_LOCATION            0x03
#define GAF_OP_BAP_CAPA_CLI_RESTORE_BOND_DATA       0x04
#define GAF_OP_BAP_CAPA_SRV_SET_RECORD              0x05
#define GAF_OP_BAP_CAPA_SRV_REMOVE_RECORD           0x06
#define GAF_OP_BAP_CAPA_SRV_RESTORE_BOND_DATA       0x07
#define GAF_OP_BAP_CAPA_SRV_SET_LOCATION            0x08
#define GAF_OP_BAP_CAPA_SRV_SET_CONTEXT             0x09

#define GAF_OP_BAP_UC_CLI_RESTORE_BOND_DATA         0x0A
#define GAF_OP_BAP_UC_CLI_RESTORE_BOND_DATA_CODEC   0x0B
#define GAF_OP_BAP_UC_CLI_CREATE_GROUP              0x0C
#define GAF_OP_BAP_UC_CLI_REMOVE_GROUP              0x0D
#define GAF_OP_BAP_UC_SRV_RESTORE_BOND_DATA         0x0E
#define GAF_OP_BAP_UC_SRV_RESTORE_BOND_DATA_CODEC   0x0F
#define GAF_OP_BAP_UC_SRV_CONFIGURE_CODEC           0x10
#define GAF_OP_BAP_UC_SRV_UPDATE_METADATA           0x11
/** @} GAF OPERARIONS COMPLETE DEFINES */

/// Response Code values for ASE Control Point characteristic
enum bap_uc_cp_rsp_code
{
    /// Success
    BAP_UC_CP_RSP_CODE_SUCCESS = 0,
    /// Unsupported Opcode
    BAP_UC_CP_RSP_CODE_UNSUPPORTED_OPCODE,
    /// Truncated Operation
    BAP_UC_CP_RSP_CODE_TRUNACTED_OPERATION,
    /// Invalid ASE ID
    BAP_UC_CP_RSP_CODE_INVALID_ASE_ID,
    /// Invalid ASE State Machine Transition
    BAP_UC_CP_RSP_CODE_INVALID_TRANSITION,
    /// Unsupported Audio Capabilities
    BAP_UC_CP_RSP_CODE_UNSUPPORTED_AUDIO_CAPA,
    /// Unsupported Configuration Parameter value
    BAP_UC_CP_RSP_CODE_UNSUPPORTED_CFG_PARAM,
    /// Rejected Configuration Parameter value
    BAP_UC_CP_RSP_CODE_REJECTED_CFG_PARAM,
    /// Invalid Configuration Parameter value
    BAP_UC_CP_RSP_CODE_INVALID_CFG_PARAM,
    /// Unsupported Metadata
    BAP_UC_CP_RSP_CODE_UNSUPPORTED_METADATA,
    /// Rejected Metadata
    BAP_UC_CP_RSP_CODE_REJECTED_METADATA,
    /// Invalid Metadata
    BAP_UC_CP_RSP_CODE_INVALID_METADATA,
    /// Insufficient Resources
    BAP_UC_CP_RSP_CODE_INSUFFICIENT_RESOURCES,
    /// Unspecified Error
    BAP_UC_CP_RSP_CODE_UNSPECIFIED_ERROR,

    BAP_UC_CP_RSP_CODE_MAX,
};

/// Reason values for ASE Control Point characteristic
enum bap_uc_cp_reason
{
    BAP_UC_CP_REASON_MIN = 1,
    /// Direction
    BAP_UC_CP_REASON_DIRECTION = BAP_UC_CP_REASON_MIN,
    /// Codec ID
    BAP_UC_CP_REASON_CODEC_ID,
    /// Codec Specific Configuration Length
    BAP_UC_CP_REASON_CODEC_CFG_LEN,
    /// Codec Specific Configuration
    BAP_UC_CP_REASON_CODEC_CFG,
    /// SDU Interval
    BAP_UC_CP_REASON_SDU_INTERVAL,
    /// Framing
    BAP_UC_CP_REASON_FRAMING,
    /// PHY
    BAP_UC_CP_REASON_PHY,
    /// Maximum SDU Size
    BAP_UC_CP_REASON_MAX_SDU_SIZE,
    /// Retransmission Number
    BAP_UC_CP_REASON_RETX_NB,
    /// Transport Latency
    BAP_UC_CP_REASON_TRANS_LATENCY,
    /// Presentation Delay
    BAP_UC_CP_REASON_PRES_DELAY,
    /// Metadata length
    BAP_UC_CP_REASON_METADATA_LEN,

    BAP_UC_CP_REASON_MAX,
};

enum gaf_bap_capa_cli_cmd_code
{
    GAF_BAP_CAPA_CLI_CMD_TYPE_DISCOVER = 0,
    GAF_BAP_CAPA_CLI_CMD_TYPE_GET,
    /// Change the characteristic value of Audio Locations for the peer service
    GAF_BAP_CAPA_CLI_CMD_TYPE_SET_LOCATION,
};

enum gaf_bap_capa_cli_req_code
{
    GAF_BAP_CAPA_CLI_REQ_TYPE_RESTORE_BOND_DATA = 0,
};

enum gaf_bap_capa_srv_req_code
{
    /// Change the characteristic value of specified PAC 
    GAF_BAP_CAPA_SRV_REQ_TYPE_SET_RECORD = 0,
    /// Remove the characteristic value of specified PAC 
    GAF_BAP_CAPA_SRV_REQ_TYPE_REMOVE_RECORD,
    GAF_BAP_CAPA_SRV_REQ_TYPE_RESTORE_BOND_DATA,
    /// Change the characteristic value of Audio Locations
    GAF_BAP_CAPA_SRV_REQ_TYPE_SET_LOCATION,
    /// Change the characteristic value of Available Audio Contexts
    GAF_BAP_CAPA_SRV_REQ_TYPE_SET_CONTEXT,
};

enum gaf_bap_uc_cli_cmd_code
{
    GAF_BAP_UC_CLI_CMD_TYPE_DISCOVER = 0,
    GAF_BAP_UC_CLI_CMD_TYPE_CONFIGURE_CODEC,
    GAF_BAP_UC_CLI_CMD_TYPE_CONFIGURE_QOS,
    GAF_BAP_UC_CLI_CMD_TYPE_ASE_ENABLE,
    GAF_BAP_UC_CLI_CMD_TYPE_UPDATE_METADATA,
    GAF_BAP_UC_CLI_CMD_TYPE_ASE_DISABLE,
    GAF_BAP_UC_CLI_CMD_TYPE_ASE_RELEASE,
    GAF_BAP_UC_CLI_CMD_TYPE_GET_QUALITY,
};

enum gaf_bap_uc_cli_req_code
{
    GAF_BAP_UC_CLI_REQ_TYPE_RESTORE_BOND_DATA = 0,
    GAF_BAP_UC_CLI_REQ_TYPE_RESTORE_BOND_DATA_CODEC,
    GAF_BAP_UC_CLI_REQ_TYPE_CREATE_GROUP,
    GAF_BAP_UC_CLI_REQ_TYPE_REMOVE_GROUP,
};

enum gaf_bap_uc_srv_cmd_code
{
    GAF_BAP_UC_SRV_CMD_TYPE_ASE_DISABLE = 0,
    GAF_BAP_UC_SRV_CMD_TYPE_ASE_RELEASE,
    GAF_BAP_UC_SRV_CMD_TYPE_GET_QUALITY,
};

enum gaf_bap_uc_srv_req_code
{
    GAF_BAP_UC_SRV_REQ_TYPE_RESTORE_BOND_DATA = 0,
    GAF_BAP_UC_SRV_REQ_TYPE_RESTORE_BOND_DATA_CODEC,
    GAF_BAP_UC_SRV_REQ_TYPE_CONFIGURE_CODEC,
    GAF_BAP_UC_SRV_REQ_TYPE_UPDATE_METADATA,
};

enum gaf_bap_uc_srv_cfm_code
{
    GAF_BAP_UC_SRV_CFM_TYPE_CONFIGURE_CODEC = 0,
    GAF_BAP_UC_SRV_CFM_TYPE_ASE_ENABLE,
    GAF_BAP_UC_SRV_CFM_TYPE_UPDATE_METADATA,
    GAF_BAP_UC_SRV_CFM_TYPE_ASE_RELEASE_RI,
};

/// Supported Roles bit field meaning
enum gaf_bap_role_bf
{
    /// Capabilities Server supported
    GAF_BAP_ROLE_SUPP_CAPA_SRV_BIT = 0x0001,
    GAF_BAP_ROLE_SUPP_CAPA_SRV_POS = 0,
    /// Capabilities Client supported
    GAF_BAP_ROLE_SUPP_CAPA_CLI_BIT = 0x0002,
    GAF_BAP_ROLE_SUPP_CAPA_CLI_POS = 1,
    /// Unicast Server supported
    GAF_BAP_ROLE_SUPP_UC_SRV_BIT = 0x0004,
    GAF_BAP_ROLE_SUPP_UC_SRV_POS = 2,
    /// Unicast Client supported
    GAF_BAP_ROLE_SUPP_UC_CLI_BIT = 0x0008,
    GAF_BAP_ROLE_SUPP_UC_CLI_POS = 3,
    /// Broadcast Source supported
    GAF_BAP_ROLE_SUPP_BC_SRC_BIT = 0x0010,
    GAF_BAP_ROLE_SUPP_BC_SRC_POS = 4,
    /// Broadcast Sink supported
    GAF_BAP_ROLE_SUPP_BC_SINK_BIT = 0x0020,
    GAF_BAP_ROLE_SUPP_BC_SINK_POS = 5,
    /// Broadcast Scan supported
    GAF_BAP_ROLE_SUPP_BC_SCAN_BIT = 0x0040,
    GAF_BAP_ROLE_SUPP_BC_SCAN_POS = 6,
    /// Broadcast Scan Assistant supported
    GAF_BAP_ROLE_SUPP_BC_ASSIST_BIT = 0x0080,
    GAF_BAP_ROLE_SUPP_BC_ASSIST_POS = 7,
    /// Broadcast Scan Delegator supported
    GAF_BAP_ROLE_SUPP_BC_DELEG_BIT  = 0x0100,
    GAF_BAP_ROLE_SUPP_BC_DELEG_POS  = 8,
};

typedef struct gaf_bap_capa_srv_cfg
{
    /// Number of PAC Groups for Sink direction
    uint8_t nb_pacs_sink;
    /// Number of PAC Groups for Source direction
    uint8_t nb_pacs_src;
    /// Configuration bit field (@see TODO [LT])
    uint8_t cfg_bf;
    /// Preferred MTU
    /// Values from 0 to 63 are equivalent to 64
    uint16_t pref_mtu;
    /// Required start handle
    /// If set to GATT_INVALID_HDL, the start handle will be automatically chosen
    uint16_t shdl;
    /// Supported Audio Locations bit field for Sink direction
    /// Meaningful only if nb_pac_sink is different than 0
    /// See @defgroup Audio Location Definitions
    uint32_t location_bf_sink;
    /// Supported Audio Locations bit field for Source direction
    /// Meaningful only if nb_pac_src is different than 0
    /// See @defgroup Audio Location Definitions
    uint32_t location_bf_src;
    /// Supported Audio Contexts bit field for Sink direction
    /// Meaningful only if nb_pac_sink is different than 0
    /// See @defgroup Context Type Definitions
    uint16_t supp_context_bf_sink;
    /// Supported Audio Contexts bit field for Source direction
    /// Meaningful only if nb_pac_src is different than 0
    /// See @defgroup Context Type Definitions
    uint16_t supp_context_bf_src;
} gaf_bap_capa_srv_cfg_t;

typedef struct gaf_bap_capa_cli_cfg
{
    /// Preferred MTU
    /// Values from 0 to 63 are equivalent to 64
    uint16_t pref_mtu;
} gaf_bap_capa_cli_cfg_t;

typedef struct gaf_bap_uc_srv_cfg
{
    /// Number of instances of the ASE characteristic
    /// Shall be in the range [0, 15]
    uint8_t nb_ase_chars;
    /// Number of ASE configurations that can be maintained
    /// Shall be at least equal to nb_ase_chars
    /// Should be a multiple of nb_ase_chars
    /// Shall not be larger than nb_ase_chars * BLE_CONNECTION_MAX
    uint8_t nb_ases_cfg;
    /// Preferred MTU
    /// Values from 0 to 63 are equivalent to 64
    uint16_t pref_mtu;
    /// Required start handle
    /// If set to GATT_INVALID_HDL, the start handle will automatically chosen
    uint16_t shdl;
    /// Direction bit field
    /// Each bit represents an ASE
    /// 0 mean sink, 1 mean source
    uint16_t direction_bf;
} gaf_bap_uc_srv_cfg_t;

typedef struct gaf_bap_uc_cli_cfg
{
    /// Configuration bit field
    uint8_t cfg_bf;
    /// Number of ASE configurations that can be maintained
    /// Shall be at least equal to nb_ase_chars
    /// Should be a multiple of nb_ase_chars
    /// Shall not be larger than nb_ase_chars * BLE_CONNECTION_MAX
    uint8_t nb_ases_cfg;
    /// Preferred MTU
    /// Values from 0 to 63 are equivalent to 64
    uint16_t pref_mtu;
} gaf_bap_uc_cli_cfg_t;

typedef struct gaf_configure_param
{
    uint32_t role_bf;
    /// Capabilities Server configuration
    gaf_bap_capa_srv_cfg_t capa_srv_cfg;
    /// Capabilities Client configuration
    gaf_bap_capa_cli_cfg_t capa_cli_cfg;
    /// Unicast Server configuration
    gaf_bap_uc_srv_cfg_t uc_srv_cfg;
    /// Unicast Client configuration
    gaf_bap_uc_cli_cfg_t uc_cli_cfg;
    /// Broadcast Scan configuration
    //bap_bc_scan_cfg_t bc_scan_cfg;
    /// Broadcast Delegator configuration
    //bap_bc_deleg_cfg_t bc_deleg_cfg;
    /// Broadcast Assistant configuration
    //bap_bc_assist_cfg_t bc_assist_cfg;
} gaf_configure_param_t;

/// Codec Identifier
typedef struct gaf_codec_id
{
    /// Codec ID value
    uint8_t codec_id[GAF_CODEC_ID_LEN];
} gaf_codec_id_t;

/// QoS Requirement structure
typedef struct bap_qos_req
{
    /// Preferred Presentation delay minimum in microseconds
    uint32_t pref_pres_delay_min_us;
    /// Preferred Presentation delay maximum in microseconds
    uint32_t pref_pres_delay_max_us;
    /// Presentation delay minimum in microseconds
    uint32_t pres_delay_min_us;
    /// Presentation delay maximum in microseconds
    uint32_t pres_delay_max_us;
    /// Preferred Transport latency maximum in milliseconds
    /// From 5ms (0x5) to 4000ms (0xFA0)
    uint16_t trans_latency_max_ms;
    /// Preferred PDU framing arrangement
    uint8_t framing;
    /// Preferred PHY bit field
    uint8_t phy_bf;
    /// Preferred maximum number of retransmissions for each CIS Data PDU
    /// From 0 to 15
    uint8_t retx_nb;
} bap_qos_req_t;

/// Broadcast code used for stream encryption
typedef struct gaf_bcast_code_t
{
    /// Broadcast Code value
    uint8_t bcast_code[GAF_KEY_LEN];
} gaf_bcast_code_t;

/// Broadcast Group Parameters structure
typedef struct bap_bc_grp_param
{
    /// SDU interval in microseconds
    uint32_t sdu_intv_us;
    /// Maximum size of an SDU
    uint16_t max_sdu;
    /// Maximum time (in milliseconds) between the first transmission of an SDU to the end of the last transmission
    /// of the same SDU
    uint16_t max_tlatency;
    /// Sequential or Interleaved scheduling
    uint8_t packing;
    /// Unframed or framed mode
    uint8_t framing;
    /// Bitfield indicating PHYs that can be used by the controller for transmission of SDUs
    uint8_t phy_bf;
    /// Number of times every PDU should be transmitted
    uint8_t rtn;
}bap_bc_grp_param_t;

/// Advertising Parameters structure
typedef struct bap_bc_adv_param
{
    /// Minimum advertising interval in multiple of 0.625ms. Must be higher than 20ms.
    uint32_t adv_intv_min_slot;
    /// Maximum advertising interval in multiple of 0.625ms. Must be higher than 20ms.
    uint32_t adv_intv_max_slot;
    /// Channel Map
    uint8_t chnl_map;
    /// PHY for primary advertising. Only LE 1M and LE Codec PHYs are allowed
    uint8_t phy_prim;
    /// PHY for secondary advertising
    uint8_t phy_second;
    /// Advertising SID
    uint8_t adv_sid;
}bap_bc_adv_param_t;

/// Periodic Advertising Parameters structure
typedef struct bap_bc_per_adv_param
{
    /// Minimum periodic advertising interval in multiple of 1.25ms. Must be higher than 7.5ms
    uint32_t adv_intv_min_frame;
    /// Maximum periodic advertising interval in multiple of 1.25ms. Must be higher than 7.5ms
    uint32_t adv_intv_max_frame;
} bap_bc_per_adv_param_t;

/// BIG Info Report
typedef struct gaf_big_info
{
    /// Value of the SDU interval in microseconds (Range 0x0000FF-0x0FFFFF)
    uint32_t  sdu_interval;
    /// Value of the ISO Interval (1.25 ms unit)
    uint16_t  iso_interval;
    /// Value of the maximum PDU size (Range 0x0000-0x00FB)
    uint16_t  max_pdu;
    /// VValue of the maximum SDU size (Range 0x0000-0x0FFF)
    uint16_t  max_sdu;
    /// Number of BIS present in the group (Range 0x01-0x1F)
    uint8_t   num_bis;
    /// Number of sub-events (Range 0x01-0x1F)
    uint8_t   nse;
    /// Burst number (Range 0x01-0x07)
    uint8_t   bn;
    /// Pre-transmit offset (Range 0x00-0x0F)
    uint8_t   pto;
    /// Initial retransmission count (Range 0x01-0x0F)
    uint8_t   irc;
    /// PHY used for transmission (0x01: 1M, 0x02: 2M, 0x03: Coded, All other values: RFU)
    uint8_t   phy;
    /// Framing mode (0x00: Unframed, 0x01: Framed, All other values: RFU)
    uint8_t   framing;
    /// True if broadcast isochronous group is encrypted, False otherwise
    bool      encrypted;
} gaf_big_info_t;

typedef struct gaf_bap_uc_cli_disc_cmd
{
    /// Connection local index
    uint8_t con_lid;
} gaf_bap_uc_cli_disc_cmd_t;

/// LC3 Parameters structure
typedef struct gaf_bap_lc3_param
{
    /// Audio Locations of audio channels being configured for the codec
    uint32_t location_bf;
    /// Number of octets for a codec frame
    uint16_t frame_octet;
    /// Sampling frequency
    uint8_t sampling_freq;
    /// Frame duration
    uint8_t frame_dur;
    /// Number of blocks of LC3 codec frames per SDU
    uint8_t nb_lc3_frames;
} gaf_bap_lc3_param_t;

/// LC3 Configuration structure
typedef struct gaf_bap_lc3_cfg
{
    /// LC3 parameters
    gaf_bap_lc3_param_t params;
    /// Length of Codec Configuration value
    uint8_t cfg_len;
    /// Codec Configuration value (in LTV format)
    uint8_t *cfg;
} gaf_bap_lc3_cfg_t;

typedef struct gaf_bap_uc_cli_cfg_codec_cmd
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE local index
    uint8_t ase_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Data Path ID
    uint8_t dp_id;
    /// Target Latency (@see enum bap_uc_tgt_latency)
    uint8_t tgt_latency;
    /// Target PHY (@see enum bap_uc_tgt_phy)
    uint8_t tgt_phy;
    /// Target PHY
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// Controller Delay in microseconds
    uint32_t ctl_delay_us;
    /// Length of Codec Configuration value
    uint16_t cfg_len;
    /// Codec Configuration value, length is cfg_len
    uint8_t *cfg;
} gaf_bap_uc_cli_cfg_codec_cmd_t;

/// QoS Configuration structure (short)
typedef struct gaf_bap_uc_cli_qos_cfg
{
    /// PHY
    uint8_t phy;
    /// Maximum number of retransmissions for each CIS Data PDU
    /// From 0 to 15
    uint8_t retx_nb;
    /// Maximum SDU size
    /// From 0 to 4095 bytes (0xFFF)
    uint16_t max_sdu_size;
    /// Presentation delay in microseconds
    uint32_t pres_delay_us;
} gaf_bap_uc_cli_qos_cfg_t;

typedef struct gaf_bap_uc_cli_cfg_qos_cmd
{
    /// ASE local index
    uint8_t ase_lid;
    /// Group local index
    uint8_t grp_lid;
    /// CIS ID
    uint8_t cis_id;
    /// QoS Configuration
    gaf_bap_uc_cli_qos_cfg_t qos_cfg;
} gaf_bap_uc_cli_cfg_qos_cmd_t;

/// Metadata for Codec Configuration structure
typedef struct gaf_bap_metadata_cfg
{
    /// Streaming audio context bit field
    uint16_t context_bf;
    /// Length of Metadata value
    uint8_t metadata_len;
    /// Metadata value
    uint8_t *metadata;
} gaf_bap_metadata_cfg_t;

typedef struct gaf_bap_uc_cli_ase_enable_cmd
{
    /// ASE local index
    uint8_t ase_lid;
    /// Metadata
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_cli_ase_enable_cmd_t;

typedef struct gaf_bap_uc_cli_update_meta_cmd
{
    /// ASE local index
    uint8_t ase_lid;
    /// Metadata
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_cli_update_meta_cmd_t;

typedef struct gaf_bap_uc_cli_ase_disable_cmd
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_cli_ase_disable_cmd_t;

typedef struct gaf_bap_uc_cli_ase_release_cmd
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_cli_ase_release_cmd_t;

typedef struct gaf_bap_uc_cli_get_quality_cmd
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_cli_get_quality_cmd_t;

typedef struct gaf_bap_uc_cli_cmd
{
    /// Command code (@see enum gaf_bap_uc_cli_cmd_code)
    uint16_t cmd_code;
    union
    {
        gaf_bap_uc_cli_disc_cmd_t disc;
        gaf_bap_uc_cli_cfg_codec_cmd_t cfg_codec;
        gaf_bap_uc_cli_cfg_qos_cmd_t cfg_qos;
        gaf_bap_uc_cli_ase_enable_cmd_t ase_enable;
        gaf_bap_uc_cli_update_meta_cmd_t update_meta;
        gaf_bap_uc_cli_ase_disable_cmd_t ase_disable;
        gaf_bap_uc_cli_ase_release_cmd_t ase_release;
        gaf_bap_uc_cli_get_quality_cmd_t get_quality;
    } data;
} gaf_bap_uc_cli_cmd_t;

/// Audio Stream Control Service characteristic description structure
typedef struct gaf_bap_uc_cli_ascs_char
{
    /// Characteristic value handle
    uint16_t val_hdl;
    /// Client Characteristic Configuration descriptor handle
    uint16_t desc_hdl;
    /// ASE ID
    uint8_t ase_id;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
} gaf_bap_uc_cli_ascs_char_t;

/// Audio Stream Control Service content description structure
typedef struct gaf_bap_uc_cli_ascs
{
    /// start handle
    uint16_t svc_shdl;
    /// end handle
    uint16_t svc_ehdl;
    /// Number of discovered ASE characteristics
    uint8_t nb_ases;
    /// Characteristic information structures
    gaf_bap_uc_cli_ascs_char_t *char_info;
} gaf_bap_uc_cli_ascs_t;

typedef struct gaf_bap_uc_cli_restore_bond_data_req
{
    /// Connection local index
    uint8_t con_lid;
    /// Audio Stream Control Service content description
    gaf_bap_uc_cli_ascs_t ascs_info;
} gaf_bap_uc_cli_restore_bond_data_req_t;

typedef struct gaf_bap_uc_cli_restore_bond_data_codec_req
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE local index
    uint8_t ase_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Data Path ID
    uint8_t dp_id;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// Controller Delay in microseconds
    uint32_t ctl_delay_us;
    /// Length of Codec Configuration value
    uint16_t cfg_len;
    /// Codec Configuration value, length is cfg_len
    uint8_t *cfg;
} gaf_bap_uc_cli_restore_bond_data_codec_req_t;

typedef struct gaf_bap_uc_cli_grp
{
    /// SDU interval from Master to Slave in microseconds
    /// From 0xFF (255us) to 0xFFFF (1.048575s)
    uint32_t sdu_intv_m2s_us;
    /// SDU interval from Slave to Master in microseconds
    /// From 0xFF (255us) to 0xFFFF (1.048575s)
    uint32_t sdu_intv_s2m_us;
    /// Maximum time (in milliseconds) for an SDU to be transported from master controller to slave
    /// controller. From 0x5 (5ms) to 0xFA0 (4s)
    uint16_t tlatency_m2s_ms;
    /// Maximum time (in milliseconds) for an SDU to be transported from slave controller to master
    /// controller. From 0x5 (5ms) to 0xFA0 (4s)
    uint16_t tlatency_s2m_ms;
    /// Sequential or interleaved scheduling
    uint8_t packing;
    /// Unframed or framed mode
    uint8_t framing;
    /// Worst slow clock accuracy of slaves
    uint8_t sca;
} gaf_bap_uc_cli_grp_t;

typedef struct gaf_bap_uc_cli_create_group_req
{
    /// CIG ID
    uint8_t cig_id;
    /// Group parameters
    gaf_bap_uc_cli_grp_t params;
} gaf_bap_uc_cli_create_group_req_t;

typedef struct gaf_bap_uc_cli_remove_group_req
{
    /// Group local index
    uint8_t grp_lid;
} gaf_bap_uc_cli_remove_group_req_t;

typedef struct gaf_bap_uc_cli_req
{
    /// Request code (@see enum gaf_bap_uc_cli_req_code)
    uint16_t req_code;
    union
    {
        gaf_bap_uc_cli_restore_bond_data_req_t restore_bd;
        gaf_bap_uc_cli_restore_bond_data_codec_req_t restore_bd_codec;
        gaf_bap_uc_cli_create_group_req_t create_group;
        gaf_bap_uc_cli_remove_group_req_t remove_group;
    } data;
} gaf_bap_uc_cli_req_t;

typedef struct gaf_bap_uc_srv_ase_disable_cmd
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_srv_ase_disable_cmd_t;

typedef struct gaf_bap_uc_srv_ase_release_cmd
{
    /// ASE local index
    uint8_t ase_lid;
    /// Indicate if ASE next state will be Idle or Codec Configured
    uint8_t idle;
} gaf_bap_uc_srv_ase_release_cmd_t;

typedef struct gaf_bap_uc_srv_get_quality_cmd
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_srv_get_quality_cmd_t;

typedef struct gaf_bap_uc_srv_cmd
{
    /// Command code (@see enum gaf_bap_uc_srv_cmd_code)
    uint16_t cmd_code;
    union
    {
        gaf_bap_uc_srv_ase_disable_cmd_t ase_disable;
        gaf_bap_uc_srv_ase_release_cmd_t ase_release;
        gaf_bap_uc_srv_get_quality_cmd_t get_quality;
    } data;
} gaf_bap_uc_srv_cmd_t;

typedef struct gaf_bap_uc_srv_restore_bond_data_req
{
    /// Connection local index
    uint8_t con_lid;
    /// Client configuration bit field for Audio Stream Control Service
    /// Each bit correspond to a characteristic in the range [0, BAP_UC_CHAR_TYPE_ASE]
    uint8_t cli_cfg_bf;
    /// Client configuration bit field for instances of the ASE characteristics
    /// Each bit correspond to an instance of the ASE characteristic
    uint16_t ase_cli_cfg_bf;
} gaf_bap_uc_srv_restore_bond_data_req_t;

typedef struct gaf_bap_uc_srv_restore_bond_data_codec_req
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE local index
    uint8_t ase_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Data Path ID
    uint8_t dp_id;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// QoS Requirements
    bap_qos_req_t qos_req;
    /// Controller delay in microseconds
    uint32_t ctl_delay_us;
    /// Length of Codec Configuration structure value
    uint16_t cfg_len;
    /// Codec Configuration structure value, length is cfg_len
    uint8_t *cfg;
} gaf_bap_uc_srv_restore_bond_data_codec_req_t;

/// Structure for BAP_UC_SRV_CONFIGURE_CODEC request message
typedef struct gaf_bap_uc_srv_cfg_codec_req
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE local index
    uint8_t ase_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// Direction
    uint8_t direction;
    /// Data Path ID
    uint8_t dp_id;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// QoS Requirements
    bap_qos_req_t qos_req;
    /// Controller delay in microseconds
    uint32_t ctl_delay_us;
    /// Length of Codec Configuration structure value
    uint16_t cfg_len;
    /// Codec Configuration structure value, length is cfg_len
    uint8_t *cfg;
} gaf_bap_uc_srv_cfg_codec_req_t;

typedef struct gaf_bap_uc_srv_update_metadata_req
{
    /// ASE local index
    uint8_t ase_lid;
    /// Metadata structure
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_srv_update_metadata_req_t;

typedef struct gaf_bap_uc_srv_req
{  
    /// Request code (@see enum gaf_bap_uc_srv_req_code)
    uint16_t req_code;
    union
    {
        gaf_bap_uc_srv_restore_bond_data_req_t restore_bd;
        gaf_bap_uc_srv_restore_bond_data_codec_req_t restore_bd_codec;
        gaf_bap_uc_srv_cfg_codec_req_t cfg_codec;
        gaf_bap_uc_srv_update_metadata_req_t update_meta;
    } data;
} gaf_bap_uc_srv_req_t;

typedef struct gaf_bap_uc_srv_cfg_codec_cfm
{
    /// Status
    uint16_t status;
    /// Response code (@see enum bap_uc_cp_rsp_code)
    uint8_t rsp_code;
    /// Reason (@see enum bap_uc_cp_reason)
    uint8_t reason;
    /// ASE local index
    uint8_t ase_lid;
    /// Data Path ID
    uint8_t dp_id;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// QoS Requirements
    bap_qos_req_t qos_req;
    /// Controller Delay in microseconds
    uint32_t ctl_delay_us;
    /// Length of Codec Configuration value
    uint16_t cfg_len;
    /// Codec Configuration value, length is cfg_len
    /// To be casted as @see bap_lc3_cfg_t for LC3
    /// To be casted as @see bap_vendor_codec_cfg_t for Vendor Codec
    uint8_t *cfg;
} gaf_bap_uc_srv_cfg_codec_cfm_t;

typedef struct gaf_bap_uc_srv_ase_enable_cfm
{
    /// Status
    uint16_t status;
    /// Response code (@see enum bap_uc_cp_rsp_code)
    uint8_t rsp_code;
    /// Reason (@see enum bap_uc_cp_reason)
    uint8_t reason;
    /// Metadata structure
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_srv_ase_enable_cfm_t;

typedef struct gaf_bap_uc_srv_update_meta_cfm
{
    /// Status
    uint16_t status;
    /// Response code (@see enum bap_uc_cp_rsp_code)
    uint8_t rsp_code;
    /// Reason (@see enum bap_uc_cp_reason)
    uint8_t reason;
    /// Metadata structure
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_srv_update_meta_cfm_t;

typedef struct gaf_bap_uc_srv_ase_release_cfm
{
    /// Status
    uint16_t status;
    /// Response code (@see enum bap_uc_cp_rsp_code)
    uint8_t rsp_code;
    /// Reason (@see enum bap_uc_cp_reason)
    uint8_t reason;
    /// Indicate if ASE next state will be Idle or Codec Configured
    uint8_t idle;
} gaf_bap_uc_srv_ase_release_cfm_t;

typedef struct gaf_bap_uc_srv_cfm
{
    /// Confirm code (@see enum gaf_bap_uc_srv_cfm_code)
    uint16_t cfm_code;
    union
    {
        gaf_bap_uc_srv_cfg_codec_cfm_t cfg_codec;
        gaf_bap_uc_srv_ase_enable_cfm_t ase_enable;
        gaf_bap_uc_srv_update_meta_cfm_t update_meta;
        gaf_bap_uc_srv_ase_release_cfm_t ase_release;
    } data;
} gaf_bap_uc_srv_cfm_t;

typedef struct gaf_bap_capa_cli_discover_cmd
{
    /// Connection local index
    uint8_t con_lid;
} gaf_bap_capa_cli_discover_cmd_t;

typedef struct gaf_bap_capa_cli_get_cmd
{
    /// Connection local index
    uint8_t con_lid;
    /// Characteristic type (@enum bap_capa_char_type)
    uint8_t char_type;
    /// PAC local index
    uint8_t pac_lid;
} gaf_bap_capa_cli_get_cmd_t;

typedef struct gaf_bap_capa_cli_set_location_cmd
{
    /// Connection local index
    uint8_t con_lid;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Location bit field
    uint32_t location_bf;
} gaf_bap_capa_cli_set_location_cmd_t;

typedef struct gaf_bap_capa_cli_cmd
{
    uint16_t cmd_code;
    union 
    {
        gaf_bap_capa_cli_discover_cmd_t disc;
        gaf_bap_capa_cli_get_cmd_t get_value;
        gaf_bap_capa_cli_set_location_cmd_t set_location;
    } data;
} gaf_bap_capa_cli_cmd_t;

typedef struct gaf_bap_capa_cli_pacs_char
{
    /// Characteristic value handle
    uint16_t val_hdl;
    /// Client Characteristic Configuration descriptor handle
    uint16_t desc_hdl;
} gaf_bap_capa_cli_pacs_char_t;

typedef struct gaf_bap_capa_cli_pacs
{
    /// start handle
    uint16_t svc_shdl;
    /// end handle
    uint16_t svc_ehdl;
    /// Number of PAC Groups for Sink direction
    uint8_t nb_pacs_sink;
    /// Number of PAC Group for Source direction
    uint8_t nb_pacs_src;
    /// Optional features bit field (@see enum bap_capa_cli_feat_bf)
    uint8_t opt_feat_bf;
    /// Characteristic information structures
    gaf_bap_capa_cli_pacs_char_t *char_info;
} gaf_bap_capa_cli_pacs_t;

typedef struct gaf_bap_capa_cli_restore_bond_data_req
{
    /// Connection local index
    uint8_t con_lid;
    /// Published Audio Capabilities Service content description
    gaf_bap_capa_cli_pacs_t pacs_info;
} gaf_bap_capa_cli_restore_bond_data_req_t;

typedef struct gaf_bap_capa_cli_req
{
    uint16_t req_code;
    union 
    {
        gaf_bap_capa_cli_restore_bond_data_req_t restore_bd;
    } data;
} gaf_bap_capa_cli_req_t;

typedef struct gaf_bap_capa_srv_restore_bond_data_req
{
    /// Connection local index
    uint8_t con_lid;
    /// Client configuration bit field
    /// Each bit corresponds to a characteristic in the range [0, BAP_CAPA_CHAR_TYPE_PAC]
    uint8_t cli_cfg_bf;
    /// Client configuration bit field for Sink/Source PAC characteristic
    /// Each bit corresponds to an instance of the Sink/Source PAC characteristic (Sink placed first)
    uint16_t pac_cli_cfg_bf;
    /// Event bit field
    /// Each bit corresponds to a characteristic in the range [0, BAP_CAPA_CHAR_TYPE_PAC]
    uint8_t evt_bf;
    /// Event configuration bit field for Sink/Source PAC characteristics
    /// Each bit corresponds to an instance of the Sink/Source PAC characteristic (Sink placed first)
    uint16_t pac_evt_bf;
    /// Available Audio Contexts for Sink direction
    uint16_t context_bf_sink;
    /// Available Audio Contexts for Source direction
    uint16_t context_bf_src;
} gaf_bap_capa_srv_restore_bond_data_req_t;

/// LC3 Capabilities structure
typedef struct gaf_bap_lc3_capa
{
    /// Supported sampling frequencies bit field
    uint16_t sampling_freq_bf;
    /// Minimum number of octets supported per codec frame
    uint16_t frame_octet_min;
    /// Maximum number of octets supported per codec frame
    uint16_t frame_octet_max;
    /// Preferred Audio Context bit field
    uint16_t context_bf;
    /// Supported frame durations bit field
    uint8_t frame_dur_bf;
    /// Channel count supported
    uint8_t chan_cnt;
    /// Maximum supported LC3 frames per SDU
    /// Shall be either equal to 0 or >= to chan_cnt
    /// Part of Codec Specific Capabilities only if different than 0
    uint8_t max_lc3_frame_sdu;
    /// Length of additional Codec Capabilities value
    uint8_t add_capa_len;
    /// Length of additional Metadata value
    uint8_t add_metadata_len;
    /// Additional Codec Capabilities value (in LTV format) followed by additional Metadata value
    /// (in LTV format)
    uint8_t *val;
} gaf_bap_lc3_capa_t;

typedef struct gaf_bap_capa_srv_set_record_req
{
    /// PAC local index
    uint8_t pac_lid;
    /// Record identifier
    uint8_t record_id;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// Length of Codec Capabilities structure value
    uint16_t capa_len;
    /// Codec Capabilities structure value
    /// To be casted as bap_lc3_capa_t for LC3.
    /// To be casted as bap_vendor_codec_capa_t for Vendor Codec
    uint8_t *capa;
} gaf_bap_capa_srv_set_record_req_t;

typedef struct gaf_bap_capa_srv_remove_record_req
{
    /// Record identifier
    uint8_t record_id;
} gaf_bap_capa_srv_remove_record_req_t;

typedef struct gaf_bap_capa_srv_set_location_req
{
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Location bit field
    uint32_t location_bf;
} gaf_bap_capa_srv_set_location_req_t;

typedef struct gaf_bap_capa_srv_set_context_req
{
    /// Context type (@see enum bap_capa_context_type)
    uint8_t context_type;
    /// Connection local index
    /// Meaningful only for Available Audio Contexts value
    /// Must be set to GAP_INVALID_CONIDX if indicated audio contexts are available for all connections
    uint8_t con_lid;
    /// Context bit field value for Sink direction
    uint16_t context_bf_sink;
    /// Context bit field value for Source direction
    uint16_t context_bf_src;
} gaf_bap_capa_srv_set_context_req_t;

typedef struct gaf_bap_capa_srv_req
{
    uint16_t req_code;
    union 
    {
        gaf_bap_capa_srv_restore_bond_data_req_t restore_bd;
        gaf_bap_capa_srv_set_record_req_t set_record;
        gaf_bap_capa_srv_remove_record_req_t remove_record;
        gaf_bap_capa_srv_set_location_req_t set_location;
        gaf_bap_capa_srv_set_context_req_t set_context;
    } data;
} gaf_bap_capa_srv_req_t;

typedef struct gaf_iso_data {
    uint16_t sdu_seq;
    uint16_t length;
    uint8_t *buffer;
    bool ts_exist;
    uint32_t ts;
} gaf_iso_data_t;

typedef struct gaf_bap_capa_cli_bond_data_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Published Audio Capabilities Service content description
    gaf_bap_capa_cli_pacs_t pacs_info;
} gaf_bap_capa_cli_bond_data_ind_t;

typedef struct gaf_bap_capa_cli_record_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// PAC local index
    uint8_t pac_lid;
    /// Record local index
    uint8_t record_lid;
    /// Number of records
    uint8_t nb_records;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// Length of Codec Capabilities value
    uint16_t capa_len;
    /// Codec Capabilities value
    uint8_t *capa;
} gaf_bap_capa_cli_record_ind_t;

typedef struct gaf_bap_capa_cli_context_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Context type (@see enum bap_capa_context_type)
    uint8_t context_type;
    /// Context type bit field for Sink direction
    uint16_t context_bf_sink;
    /// Context type bit field for Source direction
    uint16_t context_bf_src;
} gaf_bap_capa_cli_context_ind_t;

typedef struct gaf_bap_capa_cli_location_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Location bit field
    uint32_t location_bf;
} gaf_bap_capa_cli_location_ind_t;

typedef struct gaf_bap_capa_cli_cfg_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Characteristic type (@see enum bap_capa_char_type)
    uint8_t char_type;
    /// PAC local index for Sink/Source PAC characteristic
    uint8_t pac_lid;
    /// Indicate if sending of notifications is enabled (!= 0) for the indicated characteristic
    uint8_t enabled;
} gaf_bap_capa_cli_cfg_ind_t;

typedef struct gaf_bap_capa_cli_svc_changed_ind
{
    /// Connection local index
    uint8_t con_lid;
} gaf_bap_capa_cli_svc_changed_ind_t;

typedef struct gaf_bap_capa_srv_bond_data_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Client configuration bit field
    /// Each bit corresponds to a characteristic in the range [0, BAP_CAPA_CHAR_TYPE_PAC]
    uint8_t cli_cfg_bf;
    /// Client configuration bit field for Sink/Source PAC characteristic
    /// Each bit corresponds to an instance of the Sink/Source PAC characteristic (Sink placed first)
    uint16_t pac_cli_cfg_bf;
} gaf_bap_capa_srv_bond_data_ind_t;

typedef struct gaf_bap_capa_srv_location_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Location bit field
    uint32_t location_bf;
} gaf_bap_capa_srv_location_ind_t;

typedef struct gaf_bap_uc_cli_bond_data_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Audio Stream Control Service content description
    gaf_bap_uc_cli_ascs_t ascs_info;
} gaf_bap_uc_cli_bond_data_ind_t;

typedef struct gaf_bap_uc_cli_cfg_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Characteristic type
    uint8_t char_type;
    /// ASE instance index
    /// Meaningful only if configuration for an instance of the ASE characteristic is requested
    uint8_t ase_instance_idx;
    /// Enabled
    uint8_t enabled;
} gaf_bap_uc_cli_cfg_ind_ind_t;

typedef struct gaf_bap_uc_cli_cis_state_ind
{
    /// ASE local index for Sink direction
    uint8_t ase_lid_sink;
    /// ASE local index for Source direction
    uint8_t ase_lid_src;
    /// Group local index
    uint8_t grp_lid;
    /// CIS ID
    uint8_t cis_id;
    /// Connection handle allocated for the CIS by Controller
    /// GAP_INVALID_CONHDL indicates that CIS has been lost
    uint16_t conhdl;
} gaf_bap_uc_cli_cis_state_ind_t;

typedef struct gaf_bap_uc_cli_state_empty_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// ASE local index
    uint8_t ase_lid;
    /// ASE State
    uint8_t state;
} gaf_bap_uc_cli_state_empty_ind_t;

typedef struct gaf_bap_uc_cli_state_codec_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// ASE local index
    uint8_t ase_lid;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// QoS Requirements
    bap_qos_req_t qos_req;
    /// Length of Codec Configuration value
    uint16_t cfg_len;
    /// Codec Configuration value, length is cfg_len
    /// To be casted as @see bap_lc3_cfg_t for LC3
    /// To be casted as @see bap_vendor_codec_cfg_t for Vendor Codec
    uint8_t *cfg;
} gaf_bap_uc_cli_state_codec_ind_t;

typedef struct gaf_bap_qos_cfg
{
    /// PDU framing arrangement
    uint8_t framing;
    /// PHY
    uint8_t phy;
    /// Maximum number of retransmissions for each CIS Data PDU
    /// From 0 to 15
    uint8_t retx_nb;
    /// Maximum SDU size
    /// From 0 to 4095 bytes (0xFFF)
    uint16_t max_sdu_size;
    /// Transport latency in milliseconds
    /// From 5ms (0x5) to 4000ms (0xFA0)
    uint16_t trans_latency_ms;
    /// Presentation delay in microseconds
    uint32_t pres_delay_us;
    /// SDU interval in microseconds
    /// From 255us (0xFF) to 16777215us (0xFFFFFF)
    uint32_t sdu_intv_us;
} gaf_bap_qos_cfg_t;

typedef struct gaf_bap_uc_cli_state_qos_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// QoS Configuration
    gaf_bap_qos_cfg_t qos_cfg;
} gaf_bap_uc_cli_state_qos_ind_t;

typedef struct gaf_bap_uc_cli_state_metadata_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// State
    uint8_t state;
    /// Metadata
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_cli_state_metadata_ind_t;

typedef struct gaf_bap_uc_cli_svc_changed_ind
{
    /// Connection local index
    uint8_t con_lid;
} gaf_bap_uc_cli_svc_changed_ind_t;

typedef struct gaf_bap_uc_cli_error_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// Operation code
    uint8_t opcode;
    /// Response code
    uint8_t rsp_code;
    /// Reason
    uint8_t reason;
} gaf_bap_uc_cli_error_ind_t;

typedef struct gaf_bap_uc_cli_sink_iso_data_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// Time stamp is exist or not
    bool ts_exist;
    /// Time stamp
    uint32_t ts;
    /// SDU sequence number
    uint16_t sdu_seq;
    /// Data Length
    uint16_t length;
    /// Data buffer
    uint8_t *buffer;
} gaf_bap_uc_cli_sink_iso_data_ind_t;

typedef struct gaf_bap_uc_srv_bond_data_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// Client configuration bit field for Audio Stream Control Service
    /// Each bit correspond to a characteristic in the range [0, BAP_UC_CHAR_TYPE_ASE[
    uint8_t cli_cfg_bf;
    /// Client configuration bit field for instances of the ASE characteristics
    /// Each bit correspond to an instance of the ASE characteristic
    uint16_t ase_cli_cfg_bf;
} gaf_bap_uc_srv_bond_data_ind_t;

typedef struct gaf_bap_uc_srv_ase_state_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// Connection local index
    uint8_t con_lid;
    /// State (@see enum bap_uc_ase_state)
    uint8_t state;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
} gaf_bap_uc_srv_ase_state_ind_t;

typedef struct gaf_bap_uc_srv_cis_state_ind
{
    /// ASE local index for Sink direction
    uint8_t ase_lid_sink;
    /// ASE local index for Source direction
    uint8_t ase_lid_src;
    /// CIG ID
    uint8_t cig_id;
    /// CIS ID
    uint8_t cis_id;
    /// Connection handle allocated by the controller
    /// GAP_INVALID_CONHDL means that the CIS is not established
    uint16_t conhdl;
} gaf_bap_uc_srv_cis_state_ind_t;

typedef struct gaf_bap_uc_srv_sink_iso_data_ind
{
    /// Indication code (@see enum iap_msg_ind_codes)
    uint16_t ind_code;
    /// ASE local index
    uint8_t ase_lid;
    /// Time stamp is exist or not
    bool ts_exist;
    /// Time stamp
    uint32_t ts;
    /// SDU sequence number
    uint16_t sdu_seq;
    /// Data Length
    uint16_t length;
    /// Data buffer
    uint8_t *buffer;
} gaf_bap_uc_srv_sink_iso_data_ind_t;

typedef struct gaf_bap_uc_srv_configure_codec_req_ind
{
    /// Connection local index
    uint8_t con_lid;
    /// ASE instance index
    uint8_t ase_instance_idx;
    /// ASE local index
    uint8_t ase_lid;
    /// Direction (@see enum gaf_direction)
    uint8_t direction;
    /// Target Latency (@see enum bap_uc_tgt_latency)
    uint8_t tgt_latency;
    /// Target PHY (@see enum bap_uc_tgt_phy)
    uint8_t tgt_phy;
    /// Codec ID
    gaf_codec_id_t codec_id;
    /// Length of Codec Configuration value
    uint16_t cfg_len;
    /// Codec Configuration value, length is cfg_len
    /// To be casted as @see bap_lc3_cfg_t for LC3
    /// To be casted as @see bap_vendor_codec_cfg_t for Vendor Codec
    uint8_t *cfg;
} gaf_bap_uc_srv_configure_codec_req_ind_t;

typedef struct gaf_bap_uc_srv_enable_req_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// Metadata structure
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_srv_enable_req_ind_t;

typedef struct gaf_bap_uc_srv_update_metadata_req_ind
{
    /// ASE local index
    uint8_t ase_lid;
    /// Metadata structure
    gaf_bap_metadata_cfg_t metadata;
} gaf_bap_uc_srv_update_metadata_req_ind_t;

typedef struct gaf_bap_uc_srv_release_req_ind
{
    /// ASE local index
    uint8_t ase_lid;
} gaf_bap_uc_srv_release_req_ind_t;

typedef struct gaf_bap_uc_send_iso_data_cmd
{
    /// ASE local index
    uint8_t ase_lid;
    /// SDU sequence number
    uint16_t sdu_seq;
    /// Data length
    uint16_t length;
    /// ts is valid or not
    bool ts_exist;
    /// Time stamp
    uint32_t ts;
    /// Data buffer
    uint8_t *buffer;
} gaf_bap_uc_send_iso_data_cmd_t;

typedef union _gaf_callback_param {
    uint16_t status;
    struct {
        struct gap_ble_addr addr;
        uint8_t adv_sid;
        uint8_t length;
        uint8_t *data;
    } scan_report;

    struct {
        uint8_t pa_lid;
        struct gap_ble_addr addr;
        uint8_t adv_sid;
    } scan_pa_establised;

    struct {
        uint8_t pa_lid;
        uint8_t reason;
    } scan_pa_terminated;

    struct {
        uint8_t pa_lid;
        uint8_t length;
        uint8_t *data;
    } scan_pa_report;

    struct {
        uint8_t pa_lid;
        struct gaf_big_info *big_info;
    } scan_big_info_report;

    struct {
        uint8_t pa_lid;
        uint8_t nb_subgroup;
        uint8_t nb_stream;
        uint32_t pres_delay_us;
    } scan_group_report;

    struct {
        uint8_t pa_lid;
        uint8_t subgroup_lid;
        gaf_codec_id_t *codec_id;
        uint32_t stream_pos_bf;
        uint8_t cfg_len;
        uint8_t metadata_len;
        uint8_t *cfg;
        uint8_t *metadata;
    } scan_subgroup_report;

    struct {
        uint8_t pa_lid;
        uint32_t stream_pos;
        uint8_t cfg_len;
        uint8_t *cfg;
    } scan_stream_report;

    struct {
        uint8_t stream_lid;
        bool ts_exist;
        uint32_t ts;
        uint16_t sdu_seq;
        uint16_t length;
        uint8_t *buffer;
    } sink_iso_data;

    gaf_bap_capa_cli_bond_data_ind_t capa_cli_bond_data;
    gaf_bap_capa_cli_record_ind_t capa_cli_record;
    gaf_bap_capa_cli_context_ind_t capa_cli_context;
    gaf_bap_capa_cli_location_ind_t capa_cli_location;
    gaf_bap_capa_cli_cfg_ind_t capa_cli_cfg;
    gaf_bap_capa_cli_svc_changed_ind_t capa_cli_svc_changed;
    gaf_bap_capa_srv_bond_data_ind_t capa_srv_bond_data;
    gaf_bap_capa_srv_location_ind_t capa_srv_location;

    gaf_bap_uc_cli_bond_data_ind_t uc_cli_bond_data;
    gaf_bap_uc_cli_cfg_ind_ind_t uc_cli_cfg;
    gaf_bap_uc_cli_cis_state_ind_t uc_cli_cis_state;
    gaf_bap_uc_cli_state_empty_ind_t uc_cli_state_empty;
    gaf_bap_uc_cli_state_codec_ind_t uc_cli_state_codec;
    gaf_bap_uc_cli_state_qos_ind_t uc_cli_state_qos;
    gaf_bap_uc_cli_state_metadata_ind_t uc_cli_state_metadata;
    gaf_bap_uc_cli_error_ind_t uc_cli_error;
    gaf_bap_uc_cli_svc_changed_ind_t uc_cli_svc_changed;
    gaf_bap_uc_cli_sink_iso_data_ind_t uc_cli_iso_data;

    gaf_bap_uc_srv_bond_data_ind_t uc_srv_bond_data;
    gaf_bap_uc_srv_ase_state_ind_t uc_srv_ase_state;
    gaf_bap_uc_srv_cis_state_ind_t uc_srv_cis_state;
    gaf_bap_uc_srv_sink_iso_data_ind_t uc_srv_iso_data;

    gaf_bap_uc_srv_configure_codec_req_ind_t uc_srv_cfg_codec_req;
    gaf_bap_uc_srv_enable_req_ind_t uc_srv_aes_enable_req;
    gaf_bap_uc_srv_update_metadata_req_ind_t uc_srv_update_metadata_req;
    gaf_bap_uc_srv_release_req_ind_t uc_srv_ase_release_req;

    struct 
    {
        uint16_t op_code;
        uint16_t status;
    } op_cmp;
    
    struct {
        uint16_t msg_type;
        uint16_t cmd_code;
        uint16_t status;
    } unhandled_msg;
} gaf_callback_param_t;

typedef void (*gaf_callback_t)(uint8_t event, gaf_callback_param_t *param);

void gaf_cfg(gaf_callback_t cb, gaf_configure_param_t *param);


void gaf_bap_uc_cli_cmd(gaf_bap_uc_cli_cmd_t const* p_cmd);
void gaf_bap_uc_cli_req(gaf_bap_uc_cli_req_t const* p_req);
void gaf_bap_uc_srv_cmd(gaf_bap_uc_srv_cmd_t const* p_cmd);
void gaf_bap_uc_srv_req(gaf_bap_uc_srv_req_t const* p_req);
void gaf_bap_uc_srv_cfm(gaf_bap_uc_srv_cfm_t const* p_cfm);
void gaf_bap_capa_cli_cmd(gaf_bap_capa_cli_cmd_t const* p_cmd);
void gaf_bap_capa_cli_req(gaf_bap_capa_cli_req_t const* p_req);
void gaf_bap_capa_srv_req(gaf_bap_capa_srv_req_t const* p_req);

void gaf_bap_uc_srv_send_iso_data(gaf_bap_uc_send_iso_data_cmd_t const* p_cmd);
void gaf_bap_uc_cli_send_iso_data(gaf_bap_uc_send_iso_data_cmd_t const* p_cmd);

void gaf_bap_bc_src_group_add(uint8_t nb_stream, uint8_t nb_subgroups, 
                                            bap_bc_grp_param_t *grp_param,
                                            bap_bc_adv_param_t *adv_param,
                                            bap_bc_per_adv_param_t *per_adv_param);

void gaf_bap_bc_src_group_set(uint8_t grp_lid, uint32_t pres_delay_us, gaf_codec_id_t *codec_id,
                                            uint8_t cfg_len, uint8_t metadata_len, uint8_t *val);

void gaf_bap_bc_src_subgroup_set(uint8_t grp_lid, uint8_t sgrp_lid,
                                            uint8_t metadata_len, uint8_t *metadata);

void gaf_bap_bc_src_stream_set(uint8_t grp_lid, uint8_t sgrp_lid, uint8_t stream_lid, uint32_t ctl_delay_us, uint8_t dp_id,
                                            uint8_t cfg_len, uint8_t *cfg);

void gaf_bap_bc_src_pa_enable(uint8_t grp_lid, uint8_t adv_data_len, uint8_t per_adv_data_len, uint8_t *data);

void gaf_bap_bc_src_enable(uint8_t grp_lid, uint8_t encrypted, gaf_bcast_code_t *bcast_code);

void gaf_bap_bc_src_stream_start(uint8_t grp_lid, uint32_t stream_lid_bf);

void gaf_bap_bc_src_send_data(uint8_t grp_lid, uint8_t stream_lid, gaf_iso_data_t *data);

void gaf_bap_bc_scan_set_param(uint16_t intv_1m_slot, uint16_t intv_coded_slot,
                                        uint16_t wd_1m_slot, uint16_t wd_coded_slot);

void gaf_bap_bc_scan_start(uint16_t timeout_s);

void gaf_bap_bc_scan_stop(void);

void gaf_bap_bc_scan_pa_sync(struct gap_ble_addr *addr, uint8_t adv_sid, uint16_t skip, uint8_t report_filter_bf, uint16_t sync_to, uint16_t timeout_s);

void gaf_bap_bc_sink_enable(uint8_t pa_lid, uint8_t mse, uint32_t stream_pos_bf,
                                    uint16_t timeout_s,
                                    uint8_t encrypted,
                                    gaf_bcast_code_t *bcast_code);

void gaf_bap_bc_sink_stream_start(uint8_t grp_lid, uint8_t stream_pos, uint32_t ctl_delay_us,
                                            gaf_codec_id_t *codec_id,
                                            uint8_t dp_id, uint8_t cfg_len,
                                            uint8_t *cfg);

#endif  // _GAF_API_H

